Skip to content

feat(lint): add nursery rule useImportsFirst#9272

Merged
dyc3 merged 16 commits intobiomejs:mainfrom
terror:use-imports-first
Mar 10, 2026
Merged

feat(lint): add nursery rule useImportsFirst#9272
dyc3 merged 16 commits intobiomejs:mainfrom
terror:use-imports-first

Conversation

@terror
Copy link
Copy Markdown
Contributor

@terror terror commented Feb 28, 2026

Summary

Resolves #9265

This diff Implements the useImportsFirst lint rule, which enforces that all import statements appear before any non-import statements in a module. This corresponds to the ESLint import/first rule (see #9265). The rule iterates over the module item list and flags any JsImport that appears after a non-import item.

Test Plan

Snapshot tests in crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/:

  • invalid.js - imports after a const declaration (2 diagnostics)
  • invalid_mixed.js - imports interspersed with calls and exports (2 diagnostics)
  • valid.js - all imports grouped at the top (no diagnostics)
  • valid_with_export.js - single import before export and statement (no diagnostics)

Docs

Rule documentation is inline in the declare_lint_rule! macro and will be published automatically.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 28, 2026

🦋 Changeset detected

Latest commit: 7ddf5e8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Project Area: project A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis labels Feb 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 28, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a new nursery lint rule UseImportsFirst (implements biome_analyze::Rule for Ast<JsModuleItemList) that flags import statements appearing after any non‑import module item. Implements rule logic, diagnostics, and options type UseImportsFirstOptions, re-exports the options module, and registers the rule. Adds a changeset and several test specs (valid and invalid cases) under crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/.

Suggested reviewers

  • dyc3
  • ematipico
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarises the main change: adding a new nursery lint rule named useImportsFirst.
Description check ✅ Passed The description is directly related to the changeset, explaining the rule's purpose and providing test plan details.
Linked Issues check ✅ Passed The PR successfully implements the useImportsFirst rule as specified in issue #9265, enforcing imports before non-import statements.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the new rule: rule implementation, test files, options struct, and changeset documentation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js (1)

1-5: Optional: add a directive-focused valid fixture.

Given the rule docs explicitly allow directives, a tiny valid_with_directive.js (e.g. "use strict"; then imports) would lock that behaviour in and guard regressions.

Based on learnings: Add tests for all code changes - lint rules need snapshot tests in tests/specs/{group}/{rule}/.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js` around
lines 1 - 5, Add a new valid fixture file (e.g., valid_with_directive.js) under
tests/specs/nursery/useImportsFirst/ that begins with a directive like "use
strict"; followed by the same import lines (import { foo } from "foo"; import {
bar } from "bar"; import { baz } from "baz"; const qux = 1;) and the same top
comment ("should not generate diagnostics") so the test suite captures that
directives are allowed by the useImportsFirst rule; ensure the file follows the
existing snapshot test pattern used in tests/specs/{group}/{rule}/ so it is
picked up by the rule tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/biome_rule_options/src/use_imports_first.rs`:
- Line 6: Add a rustdoc comment above the public struct UseImportsFirstOptions
explaining what this options type configures (options for the
"use-imports-first" rule/assist), what each field would control (if currently
empty, state that it has no configurable fields yet and is reserved for future
settings), and include example usage or default behavior; ensure the doc uses
standard /// rustdoc format placed immediately before the declaration of
UseImportsFirstOptions.

---

Nitpick comments:
In `@crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js`:
- Around line 1-5: Add a new valid fixture file (e.g., valid_with_directive.js)
under tests/specs/nursery/useImportsFirst/ that begins with a directive like
"use strict"; followed by the same import lines (import { foo } from "foo";
import { bar } from "bar"; import { baz } from "baz"; const qux = 1;) and the
same top comment ("should not generate diagnostics") so the test suite captures
that directives are allowed by the useImportsFirst rule; ensure the file follows
the existing snapshot test pattern used in tests/specs/{group}/{rule}/ so it is
picked up by the rule tests.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 412a08d and c6d9702.

⛔ Files ignored due to path filters (7)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid_mixed.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid_with_export.js.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (7)
  • crates/biome_js_analyze/src/lint/nursery/use_imports_first.rs
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/invalid_mixed.js
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid.js
  • crates/biome_js_analyze/tests/specs/nursery/useImportsFirst/valid_with_export.js
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_imports_first.rs

@siketyan
Copy link
Copy Markdown
Member

  • Restore the PR template and fill it
  • Please add a changeset

Copy link
Copy Markdown
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a couple notes

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Feb 28, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 156 skipped benchmarks1


Comparing terror:use-imports-first (7ddf5e8) with main (2669381)2

Open in CodSpeed

Footnotes

  1. 156 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (bdcc934) during the generation of this report, so 2669381 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@github-actions github-actions bot added the A-CLI Area: CLI label Feb 28, 2026
Copy link
Copy Markdown
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

Copy link
Copy Markdown
Member

@Netail Netail left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also suggest adding a test with a directive at the beginning of a file

@terror terror requested a review from ematipico March 9, 2026 17:45
Copy link
Copy Markdown
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Left few minor comments

@terror terror requested a review from ematipico March 9, 2026 19:49
@dyc3 dyc3 merged commit 2de8362 into biomejs:main Mar 10, 2026
20 checks passed
@github-actions github-actions bot mentioned this pull request Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📎 Implement rule to enforce all imports go at the top of the file

6 participants